package araxy.blog.controller;

import araxy.blog.TotalStatus;
import araxy.blog.entity.Article;
import araxy.blog.exception.UploadException;
import araxy.blog.service.ArticleService;

import araxy.blog.utils.DateUtil;
import araxy.blog.utils.GitUtil;
import araxy.blog.utils.JsonUtil;
import araxy.blog.utils.UUIDUtil;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.util.Calendar;

import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.WRITE;

@RestController
@RequestMapping("/management")
public class ManagementController {

    @Resource
    ArticleService articleService;

    @RequestMapping("/permission-test")
    public Object permissionTest() {
        return JsonUtil.FlgTrueJSONString;
    }

    @GetMapping("/git/sync")
    public Object backupByGit() {
        String result;
        try {
            GitUtil.commitAll(DateUtil.getSysTime("yyyy-MM-dd"));
            GitUtil.push();
            result = JsonUtil.FlgTrueJSONString;
        } catch (GitAPIException e) {
            e.printStackTrace();
            result = JsonUtil.FlgFalseJSONString;
        }
        return result;
    }

    @GetMapping("/table-data/page-size/{pageSize}/page/{page}")
    public Object getManagementTableData(@PathVariable Integer page,@PathVariable Integer pageSize) {
        return articleService.getAllPagedArticle(page,pageSize);
    }

    @DeleteMapping("/article/{id}")
    public Object articleDelete(@PathVariable String id) {
        System.out.println(id);
        return articleService.deleteArticleDataById(id);
    }

    @PutMapping("/article/{id}")
    public Object articleUpdate(MultipartFile file,String desc,String title,@PathVariable String id) throws ParseException {
        Object tmp = null;
        if (file != null) {
            tmp = receiveTemp(file,id);
        }
        Article article = new Article();
        article.setId(id);
        article.setDescription(desc);
        article.setTitle(title);
        return articleService.uploadArticle(tmp,article);
    }

    @PostMapping("/article")
    public Object articleUpload(MultipartFile file, String desc, String title) {
        String id = UUIDUtil.getUUID();
        Object tmp = receiveTemp(file,id);
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        Path path = Paths.get(TotalStatus.getStorage().toString(),"articles", Integer.toString(year), Integer.toString(month));
        Article article = new Article();
        article.setDescription(desc);
        article.setTitle(title);
        article.setId(id);
        return articleService.uploadArticle(path,tmp,article);
    }

    private Object receiveTemp(MultipartFile file, String id) {
        if (file.isEmpty()) {
            throw new UploadException("文件上传失败 0");
        }
        String filename = file.getOriginalFilename();
        String fileType = filename.substring(filename.indexOf(".") + 1);
        if ( !("md".equals(fileType) || "MD".equals(fileType) || "mD".equals(fileType) || "Md".equals(fileType)) ) {
            throw new UploadException("文件不是markdown文档");
        }
        Long size = file.getSize();
        if (size > 1024*1024*10) {
            throw new UploadException("文件超出大小");
        }
        if (size < 1024*1024) {

            try {
                byte[] bytes = file.getBytes();
                ByteBuffer buf = ByteBuffer.wrap(bytes);
                return buf;
            } catch (IOException e) {
                throw new UploadException("文件上传失败 1");
            }

        } else {
            Path p = Paths.get(TotalStatus.getStorage().toString(),"temp",id);
            FileChannel in,out;
            try {
                if (Files.exists(p)) {
                    Files.delete(p);
                }
                FileInputStream fis = (FileInputStream) file.getInputStream();
                in = fis.getChannel();
                out = FileChannel.open(p,WRITE,CREATE_NEW);
                in.transferTo(0,in.size(),out);
                in.close();
                out.close();
            } catch (IOException e) {
                p.toFile().delete();
                throw new UploadException("文件上传失败 2");
            }
            return p;
        }
    }
}
